package com.rightsidetech.http.controller.userApp.login;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.rightsidetech.commom.base.ResponseData;
import com.rightsidetech.commom.config.RedisKeys;
import com.rightsidetech.commom.enums.CodeIdEnum;
import com.rightsidetech.commom.utils.BeanValidator;
import com.rightsidetech.commom.utils.RedisUtils;
import com.rightsidetech.commom.utils.StringUtil;
import com.rightsidetech.commom.utils.WXBizDataCrypt;
import com.rightsidetech.http.aspect.Log;
import com.rightsidetech.http.base.BaseController;
import com.rightsidetech.http.config.WechatConfig;
import com.rightsidetech.system.entity.SysLevelRule;
import com.rightsidetech.system.service.LevelRuleService;
import com.rightsidetech.user.dtos.requst.WxGetPhoneReq;
import com.rightsidetech.user.dtos.response.LoginResponse;
import com.rightsidetech.user.dtos.response.WechatLoginResp;
import com.rightsidetech.user.service.UserInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shenyu.client.springmvc.annotation.ShenyuSpringMvcClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import java.util.UUID;

/**
 * @author yinj
 * @Description: 微信小程序授权
 * @date 2021-10-22 10:57:53
 */
@Api(tags = "微信小程序授权相关api")
@RestController
@RequestMapping("/userApp/wechat/login")
@ShenyuSpringMvcClient(path = "/userApp/wechat/login/**")
@Slf4j
public class WeChatLoginController extends BaseController {

    @Autowired
    private WechatConfig wechatConfig;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private RedisUtils redisUtils;
    @Resource
    private LevelRuleService levelRuleService;
    @Value("${storeCodeUrl}")
    private String codeUrl;

    /**
     * 小程序获取openId
     */
    @Log
    @GetMapping(value = "/getOpenid")
    @ApiOperation(value = "小程序获取openId")
    public ResponseData<WechatLoginResp> getOpenid(String code) throws Exception {

        String params = "appid=" + wechatConfig.getAppId() + "&secret=" + wechatConfig.getSecret() + "&js_code=" + code + "&grant_type=authorization_code";
        String s = HttpUtil.get("https://api.weixin.qq.com/sns/jscode2session?" + params);
        JSONObject jsonObject = JSONObject.parseObject(s);
        String openid = jsonObject.getString("openid");
        String sessionkey = jsonObject.getString("session_key");
        WechatLoginResp wechatLoginResp = new WechatLoginResp();
        wechatLoginResp.setOpenid(openid);
        wechatLoginResp.setSessionkey(sessionkey);

        String clientIp = getAttributeForIp();
        log.info("openid ={}", openid);
        //根据openid查找用户信息
        LoginResponse loginResponse = userInfoService.getLoginResponseByOpenId(openid);
        if (!StringUtil.isNullorEmpty(loginResponse) && !StringUtils.isEmpty(loginResponse.getLoginInfoId())) {
            //黑名单用户限制登录
            if (loginResponse.getStatus() == -1){
                return ResponseData.fail("账号已冻结,请联系平台");
            }

            String token = UUID.randomUUID().toString().replace("-", "");
            //修改token;
            int count = userInfoService.updateTokenByLoginInfoId(loginResponse.getLoginInfoId(), token, clientIp);
            if (count <= 0) {
                return ResponseData.fail("用户数据不完整, 无法登录");
            }
            //设置token
            loginResponse.setToken(token);
            wechatLoginResp.setUserLoginInfo(loginResponse);
        }

        return ResponseData.success(wechatLoginResp);
    }

    @Log
    @GetMapping(value = "/loginByOpenId")
    @ApiOperation(value = "使用openId登录(测试专用)")
    public ResponseData loginByOpenId(String openId) throws Exception {
        LoginResponse loginResponse = userInfoService.getLoginResponseByOpenId(openId);
        WechatLoginResp wechatLoginResp = new WechatLoginResp();
        if(!StringUtil.isNullorEmpty(loginResponse)) {

            //黑名单用户限制登录
            if (loginResponse.getStatus() == -1){
                return ResponseData.fail("账号已冻结,请联系平台");
            }

            String token = UUID.randomUUID().toString().replace("-", "");
            //修改token;
            String clientIp = getAttributeForIp();
            int count = userInfoService.updateTokenByLoginInfoId(loginResponse.getLoginInfoId(), token, clientIp);
            if(count <= 0){
                return ResponseData.fail("用户数据不完整, 无法登录");
            }
            loginResponse.setToken(token);
            wechatLoginResp.setUserLoginInfo(loginResponse);
            wechatLoginResp.setOpenid(openId);
            return ResponseData.success(wechatLoginResp);
        }
        return ResponseData.fail("登录失败,未查到对应openId");
    }


    /**
     * 小程序获取手机号, 并注册用户
     */
    @Log
    @PostMapping(value = "/getPhone")
    @ApiOperation(value = "小程序获取手机号,并注册用户")
    public ResponseData<LoginResponse> getPhone(@RequestBody WxGetPhoneReq wxReq) throws Exception {

        ConstraintViolation validate = BeanValidator.validate(wxReq);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        String result = WXBizDataCrypt.decrypt(wxReq.getEncryptedData(), wxReq.getSessionKey(), wxReq.getIv());
        if (StrUtil.isEmpty(result)) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), "微信的加密数据包错误");
        }
        String phoneNumber = JSONObject.parseObject(result).getString("phoneNumber");
        String clientIp = getAttributeForIp();
        LoginResponse loginResponse = userInfoService.checkOpenId(wxReq.getOpenid(), clientIp);
        if (ObjectUtils.isEmpty(loginResponse)) {
            //获取会员等级规则
            SysLevelRule levelRule = levelRuleService.findLevelRuleByOrderNum(0L);
            String levelName = null;
            Byte level = 0;
            if (!ObjectUtils.isEmpty(levelRule)) {
                levelName = levelRule.getLevelName();
                level = levelRule.getLevel();
            }
            String maxMemberNo = getMaxMemberNo();
            loginResponse = userInfoService.registerUser(phoneNumber, wxReq.getOpenid(), maxMemberNo,codeUrl+maxMemberNo, "weChat", clientIp, level, levelName, wxReq.getHeadImg(), wxReq.getPetName());
        }else {
            //黑名单用户限制登录
            if (loginResponse.getStatus() == -1){
                return ResponseData.fail("账号已冻结,请联系平台");
            }
        }

        return ResponseData.success(loginResponse);
    }

    private synchronized String getMaxMemberNo() {
//        Long incr = 1L;
//        try {
//            incr = redisUtils.getIncr(RedisKeys.YS_MEMBER_NO);
//        } catch (Exception e) {
//            log.error(e.getMessage(), e);
//        }
//        if (incr == 1L) {
//            String maxMemberNo = userInfoService.getMaxMemberNo();
//            if (!StringUtils.isEmpty(maxMemberNo)) {
//                incr = Long.parseLong(maxMemberNo.replace("YS", "")) + 1;
//                redisUtils.setIncr(RedisKeys.YS_MEMBER_NO, incr);
//            }else {
//                incr = 10001L;
//                redisUtils.setIncr(RedisKeys.YS_MEMBER_NO, incr);
//            }
//        }
//        return "YS" + incr;
        long memberNo = 10001L;
        String maxMemberNo = userInfoService.getMaxMemberNo();
        if (!StringUtils.isEmpty(maxMemberNo)){
            memberNo = Long.parseLong(maxMemberNo.replace("YS", "")) + 1;
        }
        return "YS" + memberNo;
    }


}
